from constants import *

def make_progression(base,first_increment_at,next_gap,following_gap):
    progression = []
    for i in range(base):
        progression = progression + [1]
    progression = progression + [first_increment_at]
    if (next_gap + following_gap > 0):
        while max(progression)<=20:
            progression = progression + [max(progression)+next_gap,max(progression)+next_gap+following_gap]
    return progression

def value(x,progression):
    val = 0
    for i in progression:
        if x >= i:
            val = val + 1
    return val

class Item:
    def name(self):
        return ''

    def aggro(self):
        return 0

    def evasion(self):
        return 0

    def armor(self):
        return 0

    def base_damage_dice(self):
        return 0

    def base_damage_sides(self):
        return 0

    def damage(self):
        return 0

    def penetration(self):
        return 0

    def accuracy(self):
        return 0

    def speed(self):
        return 0

    def aim(self):
        return 0

    def rapidity(self):
        return 0
    
    def is_melee_weapon(self):
        return False

    def is_armor(self):
        return False

    def is_missile_weapon(self):
        return False
    
    def is_offhand(self):
        return False

    def is_trinket(self):
        return False

    def class_codes(self):
        return [C_WARRIOR,C_ROGUE,C_PRIEST,C_MAGE]

    def has_stat_requirement(self):
        return False
    
    def requires_strength(self):
        return None    

    def requires_valor(self):
        return None    

    def requires_skill(self):
        return None    

    def requires_daring(self):
        return None    

    def requires_subtlety(self):
        return None

    def requires_power(self):
        return None

    def strength(self):
        return 0

    def skill(self):
        return 0

    def valor(self):
        return 0

    def wisdom(self):
        return 0

    def daring(self):
        return 0

    def cunning(self):
        return 0

    def power(self):
        return 0

    def subtlety(self):
        return 0

    def stamina(self):
        return 0

    def constitution(self):
        return 0

    def reflexes(self):
        return 0

    def action_codes(self):
        return []

    def poison_melee(self):
        return False

    def fire_melee(self):
        return False

    def poison_missile(self):
        return False

    def fire_missile(self):
        return False

    def two_handed(self):
        return False

    def trinket_type(self):
        return None # TR_ code
    
class Body_armor(Item):
    def is_armor(self):
        return True

class Melee_weapon(Item):
    def is_melee_weapon(self):
        return True

    def hit_message(self):
        return S_HIT

    def miss_message(self):
        return S_MISS
    
class Shooter(Item):
    def is_missile_weapon(self):
        return True

    def hit_message(self):
        return S_SHOOT

    def miss_message(self):
        return S_MISS

    def class_codes(self):
        return [C_WARRIOR,C_ROGUE]

    def takes_arrows(self):
        return False

    def takes_bolts(self):
        return False

    def takes_stones(self):
        return False

class Wand(Item):
    def is_missile_weapon(self):
        return True

    def hit_message(self):
        return S_ZAP

    def miss_message(self):
        return S_MISS

    def class_codes(self):
        return [C_MAGE]

class Shield(Item):
    def is_offhand(self):
        return True

    def class_codes(self):
        return [C_WARRIOR,C_ROGUE,C_PRIEST]

class Offhand_weapon(Shield):
    def class_codes(self):
        return [C_WARRIOR,C_ROGUE]
    
class Heavy_armor(Body_armor):
    def class_codes(self):
        return [C_WARRIOR,C_PRIEST]
    
class Big_sharp_weapon(Melee_weapon):
    def class_codes(self):
        return [C_WARRIOR,C_ROGUE]

class Two_handed_sharp_weapon(Big_sharp_weapon):
    def two_handed(self):
        return True

    def class_codes(self):
        return [C_WARRIOR]

class Big_blunt_weapon(Melee_weapon):
    def class_codes(self):
        return [C_WARRIOR,C_ROGUE,C_PRIEST]

class Two_handed_blunt_weapon(Big_blunt_weapon):
    def two_handed(self):
        return True

class Trinket(Item):
    def is_trinket(self):
        return True
    
class I_E_Chainmail(Heavy_armor):
    def name(self):
        return 'Chainmail'

    def armor(self):
        return 4
    def evasion(self):
        return -1
    def speed(self):
        return -1

    def has_stat_requirement(self):
        return True
    def requires_strength(self):
        return 4
    def requires_valor(self):
        return 4

class I_E_Dwarven_chainmail(Heavy_armor):
    def name(self):
        return 'Dwarven chainmail'

    def armor(self):
        return 4
    def speed(self):
        return -1
    def constitution(self):
        return 1

    def has_stat_requirement(self):
        return True
    def requires_strength(self):
        return 4
    def requires_valor(self):
        return 4    

class I_E_Banded_mail(Heavy_armor):
    def name(self):
        return 'Banded mail'

    def armor(self):
        return 5
    def evasion(self):
        return -2
    def speed(self):
        return -1

    def has_stat_requirement(self):
        return True
    def requires_strength(self):
        return 4
    def requires_valor(self):
        return 4

class I_E_Plate_mail(Heavy_armor):
    def name(self):
        return 'Plate mail'

    def armor(self):
        return 6
    def evasion(self):
        return -2
    def speed(self):
        return -1

    def has_stat_requirement(self):
        return True
    def requires_strength(self):
        return 4
    def requires_valor(self):
        return 4  

class I_E_Cloak(Body_armor):
    def name(self):
        return 'Cloak'

    def evasion(self):
        return 2

class I_E_Tunic(Body_armor):
    def name(self):
        return 'Tunic'

    def armor(self):
        return 1

class I_E_Archers_doublet(Body_armor):
    def name(self):
        return 'Archer\'s doublet'

    def evasion(self):
        return 2
    def aim(self):
        return 1

    def class_codes(self):
        return [C_WARRIOR,C_ROGUE]
    
class I_E_Leather_cuirass(Body_armor):
    def name(self):
        return 'Leather cuirass'

    def armor(self):
        return 2
    def evasion(self):
        return -1
    
class I_E_White_robe(Body_armor):
    def name(self):
        return 'White Robe'

    def armor(self):
        return 1
    def energy(self):
        return 1

    def class_codes(self):
        return [C_PRIEST,C_MAGE]
    
class I_E_Longsword(Big_sharp_weapon):
    def name(self):
        return 'Longsword'

    def base_damage_dice(self):
        return 3
    def base_damage_sides(self):
        return 6

    def speed(self):
        return 2

    def has_stat_requirement(self):
        return True

    def requires_skill(self):
        return 3

    def requires_daring(self):
        return 3

class I_E_Flail(Two_handed_blunt_weapon):
    def name(self):
        return 'Flail'

    def base_damage_dice(self):
        return 2
    def base_damage_sides(self):
        return 12
    
    def has_stat_requirement(self):
        return True
    def requires_strength(self):
        return 4
    def requires_valor(self):
        return 4

class I_E_Greatsword(Two_handed_sharp_weapon):
    def name(self):
        return 'Greatsword'

    def base_damage_dice(self):
        return 3
    def base_damage_sides(self):
        return 7

    def speed(self):
        return 2
    
    def has_stat_requirement(self):
        return True
    def requires_strength(self):
        return 4

class I_E_Axe(Big_sharp_weapon):
    def name(self):
        return 'Axe'

    def base_damage_dice(self):
        return 3
    def base_damage_sides(self):
        return 7
    
class I_E_Antique_sword(Big_sharp_weapon):
    def name(self):
        return 'Antique sword'

    def base_damage_dice(self):
        return 3
    def base_damage_sides(self):
        return 6

    def speed(self):
        return 1
    def accuracy(self):
        return 2

    def has_stat_requirement(self):
        return True
    def requires_skill(self):
        return 4
    def requires_daring(self):
        return 4

class I_E_Rapier(Big_sharp_weapon):
    def name(self):
        return 'Rapier'

    def base_damage_dice(self):
        return 3
    def base_damage_sides(self):
        return 4

    def speed(self):
        return 2
    def evasion(self):
        return 2

    def has_stat_requirement(self):
        return True
    def requires_skill(self):
        return 4
    def requires_daring(self):
        return 4

class I_E_Champions_sword(Two_handed_sharp_weapon):
    def name(self):
        return 'Champion\'s sword'

    def base_damage_dice(self):
        return 3
    def base_damage_sides(self):
        return 8

    def speed(self):
        return 1
    def accuracy(self):
        return 2

    def has_stat_requirement(self):
        return True
    def requires_skill(self):
        return 5

    def action_codes(self):
        return [CA_LEADER]

class I_E_Dragons_bane(Big_sharp_weapon):
    def name(self):
        return 'Dragon\'s bane sword'

    def base_damage_dice(self):
        return 3
    def base_damage_sides(self):
        return 6

    def speed(self):
        return 1
    def accuracy(self):
        return 2

    def has_stat_requirement(self):
        return True
    def requires_skill(self):
        return 4

    def action_codes(self):
        return [CA_DRAGON_SLAYER]

class I_E_Spear(Big_sharp_weapon):
    def name(self):
        return 'Spear'

    def base_damage_dice(self):
        return 1
    def base_damage_sides(self):
        return 12

class I_E_Staff(Melee_weapon):
    def name(self):
        return 'Staff'

    def base_damage_dice(self):
        return 2
    def base_damage_sides(self):
        return 8

    def accuracy(self):
        return -1

class I_E_Gnarled_staff(Melee_weapon):
    def name(self):
        return 'Gnarled staff'

    def base_damage_dice(self):
        return 2
    def base_damage_sides(self):
        return 8

    def power(self):
        return 1

    def class_codes(self):
        return [C_MAGE]

class I_E_Warlock_sword(Melee_weapon):
    def name(self):
        return 'Warlock Sword'

    def base_damage_dice(self):
        return 3
    def base_damage_sides(self):
        return 7

    def action_codes(self):
        return [CA_SHOCKWAVE]

    def class_codes(self):
        return [C_MAGE]
    
class I_E_Mace(Big_blunt_weapon):
    def name(self):
        return 'Mace'

    def base_damage_dice(self):
        return 2

    def base_damage_sides(self):
        return 10

class I_E_Maul(Big_blunt_weapon):
    def name(self):
        return 'Maul'

    def base_damage_dice(self):
        return 2
    def base_damage_sides(self):
        return 14

    def speed(self):
        return -3

    def has_stat_requirement(self):
        return True
    def requires_strength(self):
        return 4
    def requires_valor(self):
        return 4

class I_E_Club(Big_blunt_weapon):
    def name(self):
        return 'Club'

    def base_damage_dice(self):
        return 2
    def base_damage_sides(self):
        return 6

    def accuracy(self):
        return -2

class I_E_Mace_of_chastisement(Big_blunt_weapon):
    def name(self):
        return 'Mace of Chastisement'

    def base_damage_dice(self):
        return 2
    def base_damage_sides(self):
        return 12

    def valor(self):
        return 1

    def has_stat_requirement(self):
        return True
    def requires_valor(self):
        return 4

    def action_codes(self):
        return [CA_SMITE]

    def class_codes(self):
        return [C_PRIEST]

class I_E_Mace_of_disruption(I_E_Mace_of_chastisement):
    def name(self):
        return 'Mace of Disruption'

    def valor(self):
        return 0

    def action_codes(self):
        return [CA_UNDEAD_SLAYER, CA_STUNNING_BLOW]
    
class I_E_Dagger(Melee_weapon):
    def name(self):
        return 'Dagger'

    def base_damage_dice(self):
        return 1
    def base_damage_sides(self):
        return 8

    def class_codes(self):
        return [C_WARRIOR,C_ROGUE,C_MAGE]

class I_E_Elven_knife(Melee_weapon):
    def name(self):
        return 'Elven knife'

    def base_damage_dice(self):
        return 1
    def base_damage_sides(self):
        return 9

    def rapidity(self):
        return 1

    def class_codes(self):
        return [C_WARRIOR,C_ROGUE]

class I_E_Assassins_blade(Melee_weapon):
    def name(self):
        return 'Assassin\'s blade'

    def base_damage_dice(self):
        return 1
    def base_damage_sides(self):
        return 25

    def poison_melee(self):
        return True

    def cunning(self):
        return 1

    def class_codes(self):
        return [C_ROGUE]

class I_E_Reliquary(Melee_weapon):
    def name(self):
        return 'Holy Reliquary'

    def base_damage_dice(self):
        return 2
    def base_damage_sides(self):
        return 3

    def wisdom(self):
        return 1

    def class_codes(self):
        return [C_PRIEST]

class I_E_Prentice_wand(Wand):
    def name(self):
        return 'Prentice wand'

    def base_damage_dice(self):
        return 1
    def base_damage_sides(self):
        return 8

class I_E_Alder_wand(Wand):
    def name(self):
        return 'Alder wand'

    def base_damage_dice(self):
        return 1
    def base_damage_sides(self):
        return 12

    def rapidity(self):
        return 2

    def has_stat_requirement(self):
        return True
    def requires_subtlety(self):
        return 3

class I_E_Hazel_wand(Wand):
    def name(self):
        return 'Hazel wand'

    def base_damage_dice(self):
        return 1
    def base_damage_sides(self):
        return 12

    def aim(self):
        return 2

    def has_stat_requirement(self):
        return True
    def requires_subtlety(self):
        return 3

class I_E_Willow_wand(Wand):
    def name(self):
        return 'Willow wand'

    def base_damage_dice(self):
        return 1
    def base_damage_sides(self):
        return 8

    def subtlety(self):
        return 1

    def has_stat_requirement(self):
        return True
    def requires_subtlety(self):
        return 3
    def requires_power(self):
        return 3

class I_E_Yew_wand(Wand):
    def name(self):
        return 'Yew wand'

    def base_damage_dice(self):
        return 1
    def base_damage_sides(self):
        return 18

    def aim(self):
        return 1

    def poison_missile(self):
        return True

    def has_stat_requirement(self):
        return True
    def requires_subtlety(self):
        return 4

class I_E_Flint_wand(Wand):
    def name(self):
        return 'Flint wand'

    def base_damage_dice(self):
        return 1
    def base_damage_sides(self):
        return 18

    def rapidity(self):
        return 1

    def fire_missile(self):
        return True

    def has_stat_requirement(self):
        return True
    def requires_power(self):
        return 4

class I_E_Shortbow(Shooter):
    def name(self):
        return 'Shortbow'

    def base_damage_dice(self):
        return 2
    def base_damage_sides(self):
        return 8

    def rapidity(self):
        return 2
    def accuracy(self):
        return 2

    def has_stat_requirement(self):
        return True
    def requires_daring(self):
        return 3
    def requires_skill(self):
        return 3

    def takes_arrows(self):
        return True

class I_E_Javelins(Shooter):
    def name(self):
        return 'Bunch of javelins'

    def base_damage_dice(self):
        return 3
    def base_damage_sides(self):
        return 4

class I_E_Longbow(Shooter):
    def name(self):
        return 'Longbow'

    def base_damage_dice(self):
        return 3
    def base_damage_sides(self):
        return 6

    def rapidity(self):
        return 1
    def accuracy(self):
        return 1

    def has_stat_requirement(self):
        return True
    def requires_daring(self):
        return 3
    def requires_skill(self):
        return 3

    def takes_arrows(self):
        return True

class I_E_Elven_bow(Shooter):
    def name(self):
        return 'Elven bow'

    def base_damage_dice(self):
        return 3
    def base_damage_sides(self):
        return 6

    def rapidity(self):
        return 1
    def accuracy(self):
        return 3

    def has_stat_requirement(self):
        return True
    def requires_daring(self):
        return 4
    def requires_skill(self):
        return 4

    def takes_arrows(self):
        return True

class I_E_Crossbow(Shooter):
    def name(self):
        return 'Crossbow'

    def base_damage_dice(self):
        return 3
    def base_damage_sides(self):
        return 8

    def rapidity(self):
        return -2
    def accuracy(self):
        return 2

    def has_stat_requirement(self):
        return True
    def requires_daring(self):
        return 3
    def requires_skill(self):
        return 3

    def takes_bolts(self):
        return True

class I_E_Gnomish_crossbow(Shooter):
    def name(self):
        return 'Gnomish crossbow'

    def base_damage_dice(self):
        return 3
    def base_damage_sides(self):
        return 8

    def rapidity(self):
        return -2
    def accuracy(self):
        return 4

    def has_stat_requirement(self):
        return True
    def requires_daring(self):
        return 4
    def requires_skill(self):
        return 4

    def takes_bolts(self):
        return True

class I_E_Sling(Shooter):
    def name(self):
        return 'Sling'

    def base_damage_dice(self):
        return 2
    def base_damage_sides(self):
        return 6

    def rapidity(self):
        return 1

    def class_codes(self):
        return [C_WARRIOR,C_ROGUE,C_PRIEST]

    def takes_stones(self):
        return True

class I_E_Buckler(Shield):
    def name(self):
        return 'Shield'

    def evasion(self):
        return 1
    
class I_E_Shield(Shield):
    def name(self):
        return 'Shield'

    def evasion(self):
        return 2

class I_E_Dwarven_shield(Shield):
    def name(self):
        return 'Dwarven shield'

    def evasion(self):
        return 2
    def constitution(self):
        return 1

    def class_codes(self):
        return [C_WARRIOR]

    def has_stat_requirement(self):
        return True
    def requires_skill(self):
        return 3

class I_E_Blazoned_shield(Shield):
    def name(self):
        return 'Blazoned shield'

    def evasion(self):
        return 3
    def aggro(self):
        return 1
    def speed(self):
        return -1

    def has_stat_requirement(self):
        return True
    def requires_skill(self):
        return 3
    def requires_daring(self):
        return 3
    def requires_valor(self):
        return 3

class I_E_Tower_shield(Shield):
    def name(self):
        return 'Tower shield'

    def evasion(self):
        return 4
    def speed(self):
        return -1

    def class_codes(self):
        return [C_WARRIOR, C_PRIEST]
    
    def has_stat_requirement(self):
        return True
    def requires_skill(self):
        return 4
    def requires_valor(self):
        return 4

class I_E_Mirrored_shield(I_E_Tower_shield):
    def name(self):
        return 'Mirrored shield'

    def action_codes(self):
        return [CA_REFLECTION]

    def aim(self):
        return -1
    
class I_E_Dirk(Offhand_weapon):
    def name(self):
        return 'Dirk'

    def speed(self):
        return 1

    def has_stat_requirement(self):
        return True
    def requires_daring(self):
        return 3
    def requires_skill(self):
        return 3

class I_E_Main_gauche(Offhand_weapon):
    def name(self):
        return 'Main gauche'

    def speed(self):
        return 2

    def has_stat_requirement(self):
        return True
    def requires_daring(self):
        return 5
    def requires_skill(self):
        return 5

class I_E_Plumed_helm(Trinket):
    def name(self):
        return 'Gaudy plumed helm'

    def trinket_type(self):
        return TR_HEADGEAR

    def aggro(self):
        return 1

class I_E_Visored_helm(Trinket):
    def name(self):
        return 'Visored helm'

    def class_codes(self):
        return [C_WARRIOR,C_PRIEST]

    def trinket_type(self):
        return TR_HEADGEAR

    def armor(self):
        return 1
    def aim(self):
        return -3

class I_E_Mirrored_helm(Trinket):
    def name(self):
        return 'Mirrored helm'

    def trinket_type(self):
        return TR_HEADGEAR

    def class_codes(self):
        return [C_WARRIOR,C_PRIEST]

    def action_codes(self):
        return [CA_STEELY_GAZE]
    
    def armor(self):
        return 1

class I_E_Chain_undervest(Trinket):
    def name(self):
        return 'Chain under-vest'

    def armor(self):
        return 1
    def speed(self):
        return -1

class I_E_Hooded_cloak(Trinket):
    def name(self):
        return 'Hooded cloak'

    def trinket_type(self):
        return TR_CLOAK

    def aggro(self):
        return -1

class I_E_Hunters_sash(Trinket):
    def name(self):
        return 'Hunter\'s sash'

    def reflexes(self):
        return 1

class I_E_Elven_arrows(Trinket):
    def name(self):
        return 'Elven arrows'

    def trinket_type(self):
        return TR_ARROWS

    def aim(self):
        return 1

    def has_stat_requirement(self):
        return True
    def requires_daring(self):
        return 4
    def requires_skill(self):
        return 4

class I_E_Poison_arrows(Trinket):
    def name(self):
        return 'Poisoned arrows'

    def trinket_type(self):
        return TR_ARROWS

    def penetration(self):
        return 3
    def poison_missile(self):
        return True

    def has_stat_requirement(self):
        return True
    def requires_daring(self):
        return 4
    def requires_skill(self):
        return 4
    
class I_E_Duellists_bracers(Trinket):
    def name(self):
        return 'Duellist\'s bracers'

    def trinket_type(self):
        return TR_BRACERS

    def rapidity(self):
        return 1

    def class_codes(self):
        return [C_MAGE]
    def has_stat_requirement(self):
        return True
    def requires_subtlety(self):
        return 4

class I_E_Bracers_of_defense(Trinket):
    def name(self):
        return 'Bracers of defense'

    def trinket_type(self):
        return TR_BRACERS

    def armor(self):
        return 1
    def action_codes(self):
        return [CA_DEFLECT_MISSILE]

    def class_codes(self):
        return [C_MAGE]
    def has_stat_requirement(self):
        return True
    def requires_subtlety(self):
        return 4

class I_E_Treasure_map(Trinket):
    def name(self):
        return 'Treasure map'

    def action_codes(self):
        return [CA_MORE_GOLD]

class I_E_Unicorn_horn(Trinket):
    def name(self):
        return 'Unicorn horn'

    def action_codes(self):
        return [CA_POISON_RESISTANCE]

class I_E_Belt_of_scalps(Trinket):
    def name(self):
        return 'Belt of scalps'

    def damage(self):
        return 1

    def class_codes(self):
        return [C_WARRIOR]
    def has_stat_requirement(self):
        return True
    def requires_strength(self):
        return 4

class I_E_Elven_boots(Trinket):
    def name(self):
        return 'Elven boots'

    def trinket_type(self):
        return TR_FOOTWEAR

    def evasion(self):
        return 1

class I_E_Flask_of_elixir(Trinket):
    def name(self):
        return 'Flask of elixir'

    def energy(self):
        return 1

class I_E_Guerdon(Trinket):
    def name(self):
        return 'Guerdon'

    def skill(self):
        return 1
    def action_codes(self):
        return [CA_RESIST_FEAR]

    def class_codes(self):
        return [C_WARRIOR]

class I_E_Ring_of_free_action(Trinket):
    def name(self):
        return 'Ring of Free Action'

    def action_codes(self):
        return [CA_FREE_ACTION]

def make_item(e_code):
    if e_code is None:
        return None
    elif e_code==E_CHAINMAIL:
        return I_E_Chainmail()
    elif e_code==E_BANDED_MAIL:
        return I_E_Banded_mail()
    elif e_code==E_TUNIC:
        return I_E_Tunic()
    elif e_code==E_CLOAK:
        return I_E_Cloak()
    elif e_code==E_WHITE_ROBE:
        return I_E_White_robe()
    elif e_code==E_LEATHER_CUIRASS:
        return I_E_Leather_cuirass()
    elif e_code==E_PLATE_MAIL:
        return I_E_Plate_mail()
    elif e_code==E_DWARVEN_CHAINMAIL:
        return I_E_Dwarven_chainmail()
    elif e_code==E_ARCHERS_DOUBLET:
        return I_E_Archers_doublet()
    elif e_code==E_LONGSWORD:
        return I_E_Longsword()
    elif e_code==E_STAFF:
        return I_E_Staff()
    elif e_code==E_MACE:
        return I_E_Mace()
    elif e_code==E_CLUB:
        return I_E_Club()
    elif e_code==E_DAGGER:
        return I_E_Dagger()
    elif e_code==E_SPEAR:
        return I_E_Spear()
    elif e_code==E_ANTIQUE_SWORD:
        return I_E_Antique_sword()
    elif e_code==E_RAPIER:
        return I_E_Rapier()
    elif e_code==E_RELIQUARY:
        return I_E_Reliquary()
    elif e_code==E_GNARLED_STAFF:
        return I_E_Gnarled_staff()
    elif e_code==E_WARLOCK_SWORD:
        return I_E_Warlock_sword()
    elif e_code==E_ELVEN_KNIFE:
        return I_E_Elven_knife()
    elif e_code==E_ASSASSINS_BLADE:
        return I_E_Assassins_blade()
    elif e_code==E_FLAIL:
        return I_E_Flail()
    elif e_code==E_GREATSWORD:
        return I_E_Greatsword()
    elif e_code==E_AXE:
        return I_E_Axe()
    elif e_code==E_CHAMPIONS_SWORD:
        return I_E_Champions_sword()
    elif e_code==E_MACE_OF_CHASTISEMENT:
        return I_E_Mace_of_chastisement()
    elif e_code==E_DRAGONS_BANE:
        return I_E_Dragons_bane()
    elif e_code==E_SHORTBOW:
        return I_E_Shortbow()
    elif e_code==E_LONGBOW:
        return I_E_Longbow()
    elif e_code==E_SLING:
        return I_E_Sling()
    elif e_code==E_CROSSBOW:
        return I_E_Crossbow()
    elif e_code==E_JAVELINS:
        return I_E_Javelins()
    elif e_code==E_ELVEN_BOW:
        return I_E_Elven_bow()
    elif e_code==E_GNOMISH_CROSSBOW:
        return I_E_Gnomish_crossbow()        
    elif e_code==E_PRENTICE_WAND:
        return I_E_Prentice_wand()
    elif e_code==E_ALDER_WAND:
        return I_E_Alder_wand()
    elif e_code==E_WILLOW_WAND:
        return I_E_Willow_wand()
    elif e_code==E_HAZEL_WAND:
        return I_E_Hazel_wand()
    elif e_code==E_YEW_WAND:
        return I_E_Yew_wand()
    elif e_code==E_FLINT_WAND:
        return I_E_Flint_wand()
    elif e_code==E_SHIELD:
        return I_E_Shield()
    elif e_code==E_BUCKLER:
        return I_E_Buckler()
    elif e_code==E_DWARVEN_SHIELD:
        return I_E_Dwarven_shield()
    elif e_code==E_BLAZONED_SHIELD:
        return I_E_Blazoned_shield()
    elif e_code==E_TOWER_SHIELD:
        return I_E_Tower_shield()
    elif e_code==E_DIRK:
        return I_E_Dirk()
    elif e_code==E_MAIN_GAUCHE:
        return I_E_Main_gauche()
    elif e_code==E_PLUMED_HELM:
        return I_E_Plumed_helm()        
    elif e_code==E_HOODED_CLOAK:
        return I_E_Hooded_cloak()        
    elif e_code==E_VISORED_HELM:
        return I_E_Main_gauche()        
    elif e_code==E_CHAIN_UNDERVEST:
        return I_E_Chain_undervest()        
    elif e_code==E_HUNTERS_SASH:
        return I_E_Hunters_sash()        
    elif e_code==E_ELVEN_ARROWS:
        return I_E_Elven_arrows()
    elif e_code==E_POISON_ARROWS:
        return I_E_Poison_arrows()       
    elif e_code==E_DUELLISTS_BRACERS:
        return I_E_Duellists_bracers()        
    elif e_code==E_BRACERS_OF_DEFENSE:
        return I_E_Bracers_of_defense()        
    elif e_code==E_UNICORN_HORN:
        return I_E_Unicorn_horn()        
    elif e_code==E_TREASURE_MAP:
        return I_E_Treasure_map()        
    elif e_code==E_BELT_OF_SCALPS:
        return I_E_Belt_of_scalps()        
    elif e_code==E_ELVEN_BOOTS:
        return I_E_Elven_boots()        
    elif e_code==E_FLASK_OF_ELIXIR:
        return I_E_Flask_of_elixir()        
    elif e_code==E_GUERDON:
        return I_E_Guerdon()
    elif e_code==E_MIRRORED_HELM:
        return I_E_Mirrored_helm()
    elif e_code==E_MIRRORED_SHIELD:
        return I_E_Mirrored_shield()
    elif e_code==E_MACE_OF_DISRUPTION:
        return I_E_Mace_of_disruption()
    elif e_code==E_MAUL:
        return I_E_Maul()
    elif e_code==E_RING_OF_FREE_ACTION:
        return I_E_Ring_of_free_action()
    else:
        return None

class Charsheet:
    def __init__(self,_class_code,_image_code,_name,_level,_intelligence,_stat1,_stat2,_constitution,_stamina,_reflexes,_action_codes,_n_obsoleted_actions,_potions,_armor,_melee_weapon,_offhand,_missile_weapon,_trinket1,_trinket2,_trinket3):
        self.class_code = _class_code
        self.name = _name
        self.image_code = _image_code
        self.level = _level
        self.stat1 = _stat1 # Str Val Dar Pow
        self.stat2 = _stat2 # Ski Wis Cun Sub
        self.intelligence = _intelligence
        self.constitution = _constitution
        self.stamina = _stamina
        self.reflexes = _reflexes
        self.master_action_codes = _action_codes
        self.n_obsoleted_actions = _n_obsoleted_actions
        self.potions = _potions # vector of POT_ codes
        self.melee_weapon = make_item(_melee_weapon)
        self.missile_weapon = make_item(_missile_weapon)
        self.offhand = make_item(_offhand)
        self.armor = make_item(_armor)
        self.trinkets = []
        if _trinket1 is not None:
            self.trinkets.append(make_item(_trinket1))
        else:
            self.trinkets.append(None)
        if _trinket2 is not None:
            self.trinkets.append(make_item(_trinket2))
        else:
            self.trinkets.append(None)
        if _trinket3 is not None:
            self.trinkets.append(make_item(_trinket3))
        else:
            self.trinkets.append(None)

    def get_n_skills(self):
        stat = self.intelligence
        if stat<=1:
            progression = make_progression(0,1,2,2)
        elif stat==2:
            progression = make_progression(0,1,1,2)
        elif stat==3:
            progression = make_progression(0,1,1,1)
        elif stat==4:
            progression = [1,1,2,3,4,5,5,6,7,8,9,9,10,11,11,12,13,13,14,15,15,16,17,17,18,19,19,20]
        elif stat==5:
            progression = [1,1,2,3,3,4,5,5,6,7,7,8,9,9,10,11,11,12,13,13,14,15,15,16,17,17,18,19,19,20]
        elif stat==6:
            progression = [1,1,2,2,3,4,4,5,5,6,7,7,8,8,9,10,10,11,11,12,13,13,14,14,15,16,16,17,17,18,19,19,20,20]
        elif stat>=7:
            progression = make_progression(2,1,1,0)
        return value(self.level,progression)
    
    def can_use(self,item):
        if not (self.class_code in item.class_codes):
            return False
        if item.has_stat_requirement():
            if (item.requires_strength() is not None):
                if item.requires_strength() <= self.get_strength():
                    return True
            if (item.requires_skill() is not None):
                if item.requires_skill() <= self.get_skill():
                    return True
            if (item.requires_daring() is not None):
                if item.requires_daring() <= self.get_daring():
                    return True
            if (item.requires_valor() is not None):
                if item.requires_valor() <= self.get_valor():
                    return True
            if (item.requires_subtlety() is not None):
                if item.requires_subtlety() <= self.get_subtlety():
                    return True
            if (item.requires_power() is not None):
                if item.requires_power() <= self.get_power():
                    return True
            return False
        return True
    
    def get_aggro(self):
        x = 0
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                x = x + item.aggro()
        return x

    def get_strength(self):
        if self.class_code==C_WARRIOR:
            x = self.stat1
        else:
            x = 2
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                x = x + item.strength()
        return x

    def get_skill(self):
        if self.class_code==C_WARRIOR:
            x = self.stat2
        else:
            x = 2
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                x = x + item.skill()
        return x

    def get_valor(self):
        if self.class_code==C_PRIEST:
            x = self.stat1
        else:
            x = 2
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                x = x + item.valor()
        return x

    def get_wisdom(self):
        if self.class_code==C_PRIEST:
            x = self.stat2
        else:
            x = 2
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                x = x + item.wisdom()
        return x

    def get_daring(self):
        if self.class_code==C_ROGUE:
            x = self.stat1
        else:
            x = 2
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                x = x + item.daring()
        return x

    def get_cunning(self):
        if self.class_code==C_ROGUE:
            x = self.stat2
        else:
            x = 2
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                x = x + item.cunning()
        return x

    def get_power(self):
        if self.class_code==C_MAGE:
            x = self.stat1
        else:
            x = 2
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                x = x + item.power()
        return x

    def get_subtlety(self):
        if self.class_code==C_MAGE:
            x = self.stat2
        else:
            x = 2
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                x = x + item.subtlety()
        return x

    def get_stamina(self):
        x = self.stamina
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                x = x + item.stamina()
        return x

    def get_reflexes(self):
        x = self.reflexes
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                x = x + item.reflexes()
        return x

    def get_constitution(self):
        x = self.constitution
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                x = x + item.constitution()
        return x
    
    def get_armor(self):
        x = 0
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                x = x + item.armor()
        return x

    def get_evasion(self):
        if self.class_code==C_WARRIOR:
            stat = self.get_skill()
        elif self.class_code==C_ROGUE:
            stat = self.get_daring()
        else:
            stat = 2
        if stat<=1:
            progression = []
        elif stat==2:
            progression = make_progression(0,5,5,5)
        elif stat==3:
            progression = make_progression(0,4,4,4)
        elif stat==4:
            progression = make_progression(0,3,3,3)
        elif stat==5:
            progression = make_progression(0,2,3,2)
        elif stat==6:
            progression = make_progression(0,1,2,2)
        elif stat>=7:
            progression = make_progression(0,1,1,2)
        x = value(self.level,progression)
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                x = x + item.evasion()
        return x

    def get_accuracy(self):
        if self.class_code==C_WARRIOR:
            stat = self.get_skill()
        elif self.class_code==C_ROGUE:
            stat = self.get_daring()
        else:
            stat = 2
        if stat<=1:
            progression = make_progression(0,5,4,4)
        elif stat==2:
            progression = make_progression(0,3,2,2)
        elif stat==3:
            progression = make_progression(0,2,1,2)
        elif stat==4:
            progression = make_progression(0,1,2,1)
        elif stat==5:
            progression = make_progression(0,1,1,2)
        elif stat==6:
            progression = make_progression(0,1,1,1)
        elif stat>=7:
            progression = [1,2,2,3,4,5,5,6,7,8,8,9,10,11,11,12,13,14,14,15,16,17,17,18,19,20,20]
        x = value(self.level,progression)
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                x = x + item.accuracy()
        return x

    def get_speed(self):
        if self.class_code==C_WARRIOR:
            stat = self.get_skill()
        elif self.class_code==C_ROGUE:
            stat = self.get_daring()
        else:
            stat = 2
        if stat<=1:
            progression = []
        elif stat==2:
            progression = []
        elif stat==3:
            progression = make_progression(0,3,5,5)
        elif stat==4:
            progression = make_progression(0,2,4,4)
        elif stat==5:
            progression = make_progression(0,1,3,3)
        elif stat==6:
            progression = make_progression(0,1,2,3)
        elif stat>=7:
            progression = make_progression(0,1,2,2)
        x = value(self.level,progression)
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                x = x + item.speed()
        return x

    def get_damage(self):
        if self.class_code==C_WARRIOR:
            stat = self.get_strength()
        elif self.class_code==C_PRIEST:
            stat = self.get_valor()
        else:
            stat = 2
        if stat<=1:
            x = -3
        elif stat==2:
            x = 0
        elif stat==3:
            x = 2
        elif stat==4:
            x = 4
        elif stat==5:
            x = 6
        elif stat==6:
            x = 7
        elif stat>=7:
            x = 10
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                x = x + item.damage()
        return x

    def get_aim(self):
        if self.class_code==C_MAGE:
            stat = self.get_subtlety()
        elif self.class_code==C_ROGUE:
            stat = self.get_daring()
        else:
            stat = 2
        if stat<=1:
            progression = make_progression(0,5,4,4)
        elif stat==2:
            progression = make_progression(0,3,2,2)
        elif stat==3:
            progression = make_progression(0,2,1,2)
        elif stat==4:
            progression = make_progression(0,1,2,1)
        elif stat==5:
            progression = make_progression(0,1,1,2)
        elif stat==6:
            progression = make_progression(0,1,1,1)
        elif stat>=7:
            progression = [1,2,2,3,4,5,5,6,7,8,8,9,10,11,11,12,13,14,14,15,16,17,17,18,19,20,20]
        x = value(self.level,progression)
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                x = x + item.aim()
        return x

    def get_rapidity(self):
        if self.class_code==C_ROGUE:
            stat = self.get_daring()
        else:
            stat = 2
        if stat<=1:
            progression = []
        elif stat==2:
            progression = []
        elif stat==3:
            progression = make_progression(0,3,5,5)
        elif stat==4:
            progression = make_progression(0,2,4,4)
        elif stat==5:
            progression = make_progression(0,1,3,3)
        elif stat==6:
            progression = make_progression(0,1,2,3)
        elif stat>=7:
            progression = make_progression(0,1,2,2)
        x = value(self.level,progression)
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                x = x + item.rapidity()
        return x

    def get_penetration(self):
        if self.class_code==C_MAGE:
            stat = self.get_power()
        else:
            stat = 2
        if stat<=1:
            x = -3
        elif stat==2:
            x = 0
        elif stat==3:
            x = 2
        elif stat==4:
            x = 4
        elif stat==5:
            x = 6
        elif stat==6:
            x = 7
        elif stat>=7:
            x = 10
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                x = x + item.penetration()
        return x

    def poison_melee(self):
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                if item.poison_melee():
                    return True
        return False

    def fire_melee(self):
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                if item.fire_melee():
                    return True
        return False

    def poison_missile(self):
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                if item.poison_missile():
                    return True
        return False

    def fire_missile(self):
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                if item.fire_missile():
                    return True
        return False

    def get_action_codes(self):
        action_codes = []
        for action_code in self.master_action_codes:
            if len(action_codes) < self.get_n_skills():
                action_codes.append(action_code)
        for item in [self.armor, self.offhand, self.melee_weapon, self.missile_weapon, self.trinkets[0], self.trinkets[1], self.trinkets[2]]:
            if item is not None:
                for action_code in item.action_codes():
                    if not (action_code in action_codes):
                        action_codes.append(action_code)
        return action_codes

# _intelligence,_stat1 (St V D P),_stat2 (Sk W C Su),_constitution,_stamina,_reflexes
    
charsheets1 = []
charsheets1.append(Charsheet(C_PRIEST,  I_PRIEST_3, 'Tank',     6, 3,4,3,6,3,1, [CA_RIGHTEOUSNESS,CA_FRONT_ROW_BUFF,CA_SELF_HEAL,CA_AGGRO,CA_ARMOR,CA_RESIST_FEAR],0,                                                [POT_PERCENTHEAL,POT_FIRE_RESIST,POT_COLD_RESIST], E_PLATE_MAIL,E_MACE,E_BLAZONED_SHIELD,None,E_PLUMED_HELM,E_CHAIN_UNDERVEST,None))
charsheets1.append(Charsheet(C_WARRIOR, I_WARRIOR_2,'Brute',    6, 3,6,5,2,3,1, [CA_SMITE,CA_RETRENCH,CA_DEFLECT,CA_BLOCK,CA_PROTECT_THE_FALLEN],1,                                                                  [POT_PERCENTHEAL,POT_ANTIDOTE,POT_BERSERK],        E_CHAINMAIL,E_GREATSWORD,None,None,E_BELT_OF_SCALPS,None,None))
charsheets1.append(Charsheet(C_WARRIOR, I_WARRIOR_3,'Thug',     6, 3,6,5,2,3,1, [CA_SMITE,CA_CLEAVE,CA_RETRENCH,CA_KNOCKBACK],2,                                                                                     [POT_SMALLHEAL,POT_MEDHEAL,POT_BIGHEAL],           E_CHAINMAIL,E_GREATSWORD,None,None,E_BELT_OF_SCALPS,None,None))
charsheets1.append(Charsheet(C_PRIEST,  I_PRIEST_2, 'Medic',    6, 3,1,5,1,6,4, [CA_HEALER,CA_SMALL_HEAL,CA_MASS_HEAL,CA_CURE_POISON,CA_CURE_FEAR],1,                                                                [POT_BAR_PRIEST,POT_INVULNERABILITY],              E_BANDED_MAIL,E_RELIQUARY,E_SHIELD,None,E_FLASK_OF_ELIXIR,None,None))
charsheets1.append(Charsheet(C_MAGE,    I_MAGE_3,   'Artillery',6, 5,6,1,1,6,1, [CA_FIREBOLT,CA_LIGHTNING_BOLT,CA_BLOOD_MAGIC,CA_POISON_CLOUD_2,CA_DISPELL,CA_REFLECTION,CA_COUNTERSPELL_PARALYSIS],2,               [POT_BAR_MAGE,POT_COURAGE],                        E_WHITE_ROBE,E_GNARLED_STAFF,None,E_PRENTICE_WAND,None,None,None)) 
charsheets1.append(Charsheet(C_ROGUE,   I_ROGUE_1,  'Sniper',   6, 3,6,1,1,4,5, [CA_SNIPE,CA_LUCKY_SHOT,CA_PENETRATION,CA_ACCURATE_SHOT,CA_MAGEBANE,CA_RUTHLESS],0,                                                  [POT_BAR_ROGUE],                                   E_ARCHERS_DOUBLET,E_ELVEN_KNIFE,None,E_ELVEN_BOW,E_POISON_ARROWS,None,None))

charsheets2 = []
charsheets2.append(Charsheet(C_WARRIOR, I_WARRIOR_1,'Thrax',    6, 3,3,4,3,2,5, [CA_BLOCK,CA_DEFLECT,CA_BASH,CA_RETRENCH,CA_PROTECT_THE_FALLEN,CA_LEADER],0,                                                        [POT_MEDHEAL,POT_MEDHEAL], E_BANDED_MAIL,E_ANTIQUE_SWORD,E_DWARVEN_SHIELD,None,E_HUNTERS_SASH,None,None))
charsheets2.append(Charsheet(C_WARRIOR, I_WARRIOR_3,'Matachin', 6, 3,6,4,3,3,1, [CA_SMITE,CA_CLEAVE,CA_RAGE,CA_STUNNING_BLOW],2,                                                                                    [POT_MEDHEAL,POT_MEDHEAL], E_PLATE_MAIL,E_GREATSWORD,None,None,E_BELT_OF_SCALPS,None,None))
charsheets2.append(Charsheet(C_ROGUE,   I_ROGUE_2,  'Ascia',    6, 5,5,3,3,3,1, [CA_DODGE,CA_WEAKEN,CA_RUTHLESS,CA_FIND_TRAPS,CA_LUCKY_ESCAPE,CA_INCONSPICUOUS,CA_VENDETTA,CA_SNIPE,CA_UNDEAD_SLAYER],0,            [POT_MEDHEAL,POT_MEDHEAL], E_CLOAK,E_RAPIER,E_SHIELD,E_LONGBOW,E_UNICORN_HORN,None,None))
charsheets2.append(Charsheet(C_PRIEST,  I_PRIEST_2, 'Gyoll',    6, 4,1,5,2,5,3, [CA_HEALING,CA_SACRIFICE,CA_TURN_UNDEAD,CA_CURE_POISON,CA_RESIST_FIRE,CA_MASS_HEAL,CA_REVITALISE,CA_SLING],0,                       [],                        E_BANDED_MAIL,E_RELIQUARY,E_SHIELD,E_SLING,None,None,None))
charsheets2.append(Charsheet(C_MAGE,    I_MAGE_3,   'Saltus',   6, 3,6,1,3,6,1, [CA_FIREBOLT,CA_LIGHTNING_BOLT,CA_BLOOD_MAGIC,CA_WAND_LORE,CA_STICKY_FLAMES],1,                                                     [POT_BAR_MAGE],            E_WHITE_ROBE,E_STAFF,None,E_HAZEL_WAND,E_DUELLISTS_BRACERS,None,None)) 
charsheets2.append(Charsheet(C_MAGE,    I_MAGE_1,   'Nessus',   6, 4,3,5,1,5,2, [CA_CONFUSION,CA_FIREBOLT,CA_COUNTERSPELL_PARALYSIS,CA_COUNTER_FEAR,CA_REFLECTION,CA_COUNTER_SLEEP,CA_DECONSTRUCT,CA_EXTINGUISH],0, [POT_BAR_MAGE],            E_CLOAK,E_STAFF,None,E_YEW_WAND,E_RING_OF_FREE_ACTION,None,None))

charsheets3 = []
charsheets3.append(Charsheet(C_PRIEST,  I_PRIEST_3, 'Gyoll', 5, 4,3,2,5,3,3, [CA_BLOCK,CA_SACRIFICE,CA_SELF_HEAL,CA_AGGRO,CA_ARMOR,CA_RIGHTEOUSNESS,CA_FRONT_ROW_BUFF],0,            [POT_MEDHEAL], E_BANDED_MAIL,E_MACE,E_SHIELD,None,          None,None,None))
charsheets3.append(Charsheet(C_WARRIOR, I_WARRIOR_3,'Thrax', 5, 1,6,5,3,4,1, [CA_BASH,CA_SWIPE,CA_RETRENCH],0,                                                                       [POT_MEDHEAL], E_LEATHER_CUIRASS,E_AXE,None,None,           None,None,None))
charsheets3.append(Charsheet(C_ROGUE,   I_ROGUE_2,  'Ascia', 5, 3,6,3,3,4,1, [CA_RUTHLESS,CA_WEAKEN,CA_AMBUSH,CA_INCONSPICUOUS,CA_FIND_WEAKNESS],0,                                  [],            E_CLOAK,E_LONGSWORD,E_MAIN_GAUCHE,E_SHORTBOW,None,None,None))
charsheets3.append(Charsheet(C_MAGE,    I_MAGE_3,   'Saltus',5, 4,6,2,1,6,1, [CA_LIGHTNING_BOLT,CA_COUNTERSPELL_PARALYSIS,CA_INVULNERABILITY,CA_STICKY_FLAMES,CA_SHOCKING_GRASP],1,  [POT_BAR_MAGE],E_CLOAK,E_STAFF,None,E_ALDER_WAND,           None,None,None))

charsheets4 = []
charsheets4.append(Charsheet(C_PRIEST,  I_PRIEST_3, 'Tank',     4, 3,4,3,6,3,1, [CA_RIGHTEOUSNESS,CA_SELF_HEAL,CA_AGGRO,CA_RESIST_FEAR],0,                                    [POT_SMALLHEAL],                                 E_CHAINMAIL,E_MACE,E_SHIELD,None,None,E_CHAIN_UNDERVEST,None))
charsheets4.append(Charsheet(C_WARRIOR, I_WARRIOR_2,'Brute',    4, 3,6,5,2,3,1, [CA_BASH,CA_RETRENCH,CA_DEFLECT,CA_BLOCK],0,                                                  [POT_PERCENTHEAL,POT_ANTIDOTE,POT_FIRE_RESIST],  E_CHAINMAIL,E_AXE,None,None,None,None,None))
charsheets4.append(Charsheet(C_WARRIOR, I_WARRIOR_3,'Thug',     4, 3,6,5,2,3,1, [CA_SMITE,CA_SWIPE,CA_RETRENCH],1,                                                            [POT_SMALLHEAL],                                 E_CHAINMAIL,E_AXE,None,None,E_BELT_OF_SCALPS,None,None))
charsheets4.append(Charsheet(C_PRIEST,  I_PRIEST_2, 'Medic',    4, 3,1,5,1,6,4, [CA_HEALER,CA_SMALL_HEAL,CA_CURE_POISON],1,                                                   [],                                              E_CHAINMAIL,E_MACE,E_SHIELD,None,None,None,None))
charsheets4.append(Charsheet(C_MAGE,    I_MAGE_3,   'Artillery',4, 5,6,1,1,6,1, [CA_LIGHTNING_BOLT,CA_BLOOD_MAGIC,CA_POISON_CLOUD,CA_REFLECTION,CA_COUNTERSPELL_PARALYSIS],1, [POT_BAR_MAGE,],                                 E_TUNIC,E_GNARLED_STAFF,None,E_PRENTICE_WAND,None,None,None)) 
charsheets4.append(Charsheet(C_ROGUE,   I_ROGUE_1,  'Sniper',   4, 3,6,1,1,4,5, [CA_SNIPE,CA_PENETRATION,CA_ACCURATE_SHOT,CA_RUTHLESS],0,                                     [POT_BAR_ROGUE],                                 E_CLOAK,E_RAPIER,None,E_LONGBOW,None,None,None))

charsheets5 = []
charsheets5.append(Charsheet(C_WARRIOR, I_WARRIOR_1,'Thrax',    4, 3,3,4,3,2,5, [CA_BLOCK,CA_DEFLECT,CA_BASH,CA_LEADER],0,                                    [POT_MEDHEAL], E_CHAINMAIL,E_LONGSWORD,E_SHIELD,None,None,None,None))
charsheets5.append(Charsheet(C_WARRIOR, I_WARRIOR_3,'Matachin', 4, 3,6,4,3,3,1, [CA_BASH,CA_CLEAVE,CA_RAGE,],1,                                               [POT_MEDHEAL], E_CHAINMAIL,E_AXE,None,None,E_BELT_OF_SCALPS,None,None))
charsheets5.append(Charsheet(C_ROGUE,   I_ROGUE_2,  'Ascia',    4, 5,5,3,3,3,1, [CA_DODGE,CA_WEAKEN,CA_RUTHLESS,CA_FIND_TRAPS,CA_LUCKY_ESCAPE,CA_VENDETTA],0, [POT_MEDHEAL], E_CLOAK,E_RAPIER,E_SHIELD,E_LONGBOW,E_UNICORN_HORN,None,None))
charsheets5.append(Charsheet(C_PRIEST,  I_PRIEST_2, 'Gyoll',    4, 4,1,5,2,5,3, [CA_HEALING,CA_SACRIFICE,CA_TURN_UNDEAD,CA_CURE_POISON,CA_RESIST_FIRE],0,     [],            E_CHAINMAIL,E_MACE,E_SHIELD,None,None,None,None))
charsheets5.append(Charsheet(C_MAGE,    I_MAGE_3,   'Saltus',   4, 3,6,1,3,6,1, [CA_FIREBOLT,CA_LIGHTNING_BOLT,CA_BLOOD_MAGIC],1,                             [],            E_TUNIC,E_STAFF,None,E_HAZEL_WAND,E_DUELLISTS_BRACERS,None,None)) 
charsheets5.append(Charsheet(C_MAGE,    I_MAGE_1,   'Nessus',   4, 4,3,5,1,5,2, [CA_CONFUSION,CA_FIREBOLT,CA_COUNTERSPELL_PARALYSIS,CA_COUNTER_FEAR,CA_REFLECTION],0, [],    E_CLOAK,E_STAFF,None,E_ALDER_WAND,None,None,None))

parties = {}
parties['Tanked L6 party'] = charsheets1
parties['Untanked L6 party'] = charsheets2
parties['Tanked L4 party'] = charsheets4
parties['Untanked L4 party'] = charsheets5


# NOTES

# Need to think about skill tree. Note Skills have already been superseded by lightning bolt, poison cloud 2, wand lore 2, smite and cleave.
# Many skills should be level restricted.

# Strength prerequisites - Stunning Blow, Rage
# Skill prerequisites - Deflect, Block, Shoot, Epic Block
# Wisdom prerequisites - Cure Poison, Resist Fire, Cure Fear, Meditation
# Constitution prerequisites - Fire Resistance, Poison Resistance, Fear Resistance
# Valor prerequisites - Sling, Righteousness, Armor, Frontrowbuff, Curse
# Wisdom prerequisites - Reveal Danger, Cleansing Flame (6+)
# Cunning prerequisites - Find Traps, Ambush, Weaken, Bribe, Confusing Spiel, Distraction
# Daring prerequisites - Lucky Shot, Snipe, Leap Aside, Free Action
# Subtlety prerequisites - Fly, Deflect Missile, Word of Recall, Extinguish, Detect Magic
# Power prerequisites - Sticky Flames, Shocking Grasp, Shockwave, Dispell, Force Cage
# Reflex prerequisites - Veteran, Ruthless

# Give Priest access to Dispell (requiring Wis), Smite, Block (requiring Valor), Fear Resistance, Leader, Word of Recall (requiring Wisdom, and dont forget to give xp), Concentration, Protect the Fallen, Counter: Draining
# Give Rogue access to Undead Slayer (as "Grave Robber"), Taunt, Ruthless, Fear Resistance, Leader, Deathblow, Word of Recall (requiring Cunning, as Quick Exit), Slow Time (requiring Cunning, as Quick Thinking)
# Give Mage access to Ruthless, Stealth (as "Cloak of Shadows", requiring a lot of Subtlety)

# Upgrade in-game chardump to a gui view

# Don't let two items of the same trinket type be worn
# Don't allow trinkets of an ammo type that doesn't match the shooter type
# Don't let a two-handed weapon be wielded with a shield
# Don't let items of the wrong class be worn
# Don't let items be worn if the stat prerequisites are not met
# Don't let warriors wield missile weapons if they don't have CA_SHOOT, or priests if they don't have CA_SLING
